package com.zmn.oms.dubbo.impl.normal.apply;

import com.github.ltsopensource.core.json.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.consts.GateTypeConsts;
import com.zmn.mos.common.dio.order.add.NormalOrderAddDIO;
import com.zmn.mos.common.dio.order.add.nest.OrderBaseInfo;
import com.zmn.mos.common.dio.order.add.nest.OrderDistributeMasterDIO;
import com.zmn.mos.common.dio.order.add.nest.OrderProductDIO;
import com.zmn.mos.common.dio.order.add.nest.UserDIO;
import com.zmn.mos.common.dro.order.OrderAddDRO;
import com.zmn.mos.dubbo.interfaces.order.NormalOrderRemoteService;
import com.zmn.oms.business.interfaces.order.DuplicateOrderBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dio.normal.apply.RebuildOrderDIO;
import com.zmn.oms.common.dro.normal.apply.RebuildOrderDRO;
import com.zmn.oms.dubbo.interfaces.normal.apply.CancelApplyRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.work.DistributeVO;
import com.zmn.oms.model.vo.work.ZsOrderDistributeVO;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.order.OrderService;
import com.zmn.oms.services.interfaces.product.OrderProductService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.track.dubbo.interfaces.apply.cancel.OrderCancelApplyListRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Objects;

/**
 * @Author: wyc
 * @Description:
 * @Date: 2022/5/27 15:29
 * @Version: 1.0
 */
@Slf4j
@Service(loadbalance = "roundrobin", timeout = 20000, retries = 0, version = DubboConsts.INTERFACE_VERSION, validation = "true")
public class CancelApplyRemoteServiceImpl implements CancelApplyRemoteService {

    @Reference(version = com.zmn.track.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private OrderCancelApplyListRemoteService orderCancelApplyListRemoteService;
    @Reference(version = com.zmn.mos.dubbo.utils.DubboConsts.INTERFACE_VERSION, timeout = 10000, check = false)
    private NormalOrderRemoteService normalOrderRemoteService;

    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderProductService orderProductService;
    @Autowired
    private DuplicateOrderBService duplicateOrderBService;

    @Override
    public ResponseDTO<RebuildOrderDRO> rebuildOrder(RebuildOrderDIO rebuildOrderDIO) {
        log.info("取消申请重建订单#rebuildOrder dio={}",rebuildOrderDIO);
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(rebuildOrderDIO.getOriginalOrderId(), rebuildOrderDIO.getOriginalWorkId());
        if (Objects.isNull(orderWork)) {
            ResponseDTO.fail("源工单不存在！");
        }
        if (Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            ResponseDTO.fail("源工单还在进行中！");
        }
        if (Objects.isNull(orderWork.getCancelTime())) {
            ResponseDTO.fail("源工单未取消！");
        }
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(rebuildOrderDIO.getOriginalOrderId());
        List<OrderProduct> orderProductList = orderProductService.listOrderProductByOrderId(rebuildOrderDIO.getOriginalOrderId());

        // 操作信息
        NormalOrderAddDIO normalOrderAddDIO = new NormalOrderAddDIO();
        normalOrderAddDIO.setOperator(rebuildOrderDIO.getOperator());
        normalOrderAddDIO.setOperatorId(rebuildOrderDIO.getOperatorId());
        normalOrderAddDIO.setOperatorType(rebuildOrderDIO.getOperatorType());

        normalOrderAddDIO.setServCategId(orderWork.getServCategId());

        // 基础信息
        OrderBaseInfo orderBaseInfo = new OrderBaseInfo();
        orderBaseInfo.setPlat(orderWork.getPlatWork());
        orderBaseInfo.setBizType(orderWork.getBizType());
        // 使用源渠道
        orderBaseInfo.setChannelId(orderWork.getChannelId());
        orderBaseInfo.setSourceChannelId(orderWork.getSourceChannelId());

        orderBaseInfo.setType(OrderConsts.ORDER_TYPE_NEW);
        orderBaseInfo.setTest(orderWork.getTest());
        orderBaseInfo.setOriginalId(orderWork.getOrderId());
        orderBaseInfo.setReceiveEntranceId(GateTypeConsts.GATE_PLAT_BACKSTAGE);
        normalOrderAddDIO.setOrderBaseInfo(orderBaseInfo);

        // 用户信息
        UserDIO userDIO = new UserDIO();
        userDIO.setUserId(orderWork.getUserId());
        userDIO.setUserName(orderDetail.getUserName());
        userDIO.setTelephone(orderDetail.getTelephone());
        userDIO.setTelephone2(orderDetail.getTelephone2());
        userDIO.setTelephone3(orderDetail.getTelephone3());
        userDIO.setUserType(orderDetail.getUserType());
        userDIO.setContactName(orderDetail.getContactName());
        userDIO.setGender(orderDetail.getGender());
        userDIO.setCityId(orderWork.getCityId());
        userDIO.setCountyId(orderDetail.getCountyId());
        userDIO.setStreetSource(orderDetail.getStreetSource());
        userDIO.setStreetId(orderDetail.getStreetId());
        userDIO.setStreet(orderDetail.getStreet());
        userDIO.setAddress(orderDetail.getAddress());
        userDIO.setLongitude(orderDetail.getLongitude());
        userDIO.setLatitude(orderDetail.getLatitude());
        normalOrderAddDIO.setUserDIO(userDIO);
        // 产品信息
        OrderProductDIO orderProductAddDIO = new OrderProductDIO();
        OrderProduct orderProduct = orderProductList.get(0);
        // 预约时间往后推一个小时
        orderProductAddDIO.setDutyTime(DateUtil.addMinute(DateUtil.getNow(), 60));
        orderProductAddDIO.setBrandId(orderProduct.getBrandId());
        orderProductAddDIO.setServCategId(orderWork.getServCategId());
        orderProductAddDIO.setCategId(orderProduct.getCategId());
        orderProductAddDIO.setProductId(orderProduct.getProductId());
        orderProductAddDIO.setShowProductId(orderProduct.getShowProductId());
        orderProductAddDIO.setNumber(orderProduct.getNumber());
        orderProductAddDIO.setRemark(orderProduct.getRemark());
        orderProductAddDIO.setFault(orderProduct.getFault());
        List<OrderProductDIO> orderProductDIOS = Lists.newArrayList(orderProductAddDIO);
        normalOrderAddDIO.setOrderProductList(orderProductDIOS);

        // 预派工程师
        if (NumberUtil.isNotNullOrZero(rebuildOrderDIO.getOriginalMasterId())) {
            OrderDistributeMasterDIO orderDistributeMasterDIO = new OrderDistributeMasterDIO();
            orderDistributeMasterDIO.setDistributeMasterId(rebuildOrderDIO.getOriginalMasterId());
            DistributeVO distributeVO = new DistributeVO();
            ZsOrderDistributeVO autoDistributeMaster = new ZsOrderDistributeVO();
            autoDistributeMaster.setMasterId(rebuildOrderDIO.getOriginalMasterId());
            autoDistributeMaster.setMasterName(rebuildOrderDIO.getOriginalMasterName());
            autoDistributeMaster.setMasterPhone(rebuildOrderDIO.getOriginalMasterPhone());
            autoDistributeMaster.setDistributeRelateWorkText("取消申请重建订单指定派");
            distributeVO.setAutoDistributeMaster(autoDistributeMaster);
            orderDistributeMasterDIO.setDistributeJsonStr(JSON.toJSONString(distributeVO));
            List<OrderDistributeMasterDIO> distributeMasterList = Lists.newArrayList(orderDistributeMasterDIO);
            normalOrderAddDIO.setDistributeMasterList(distributeMasterList);
        }

        log.info("重建新单#normalOrderRemoteService#addOrder入参：[{}]", JSON.toJSONString(normalOrderAddDIO));
        ResponseDTO<OrderAddDRO> responseDTO = normalOrderRemoteService.addOrder(normalOrderAddDIO);
        log.info("重建新单#normalOrderRemoteService#addOrder出参：[{}]", JSON.toJSONString(responseDTO));
        if (!responseDTO.isSuccess()){
            ResponseDTO.fail(responseDTO.getStatus(), responseDTO.getMessage());
        }

        // 返回dro
        RebuildOrderDRO dro = new RebuildOrderDRO();
        dro.setOrderId(responseDTO.getData().getOrderId());
        dro.setWorkId(responseDTO.getData().getOrderId());
        OrderDetail newOrderDetail = orderDetailService.findOrderDetailByKey(responseDTO.getData().getOrderId());
        if (Objects.nonNull(newOrderDetail)) {
            StringBuilder address = new StringBuilder();
            address.append(orderDetail.getProvinceName()).append(newOrderDetail.getCityName()).append(newOrderDetail.getCountyName())
                    .append(StringUtils.defaultString(newOrderDetail.getStreet())).append(StringUtils.defaultString(newOrderDetail.getAddress()))
                    .append("经纬度：").append(newOrderDetail.getLongitude()).append(",").append(newOrderDetail.getLatitude());
            dro.setAddressInfo(address.toString());
        }
        List<OrderProduct> newOrderProductList = orderProductService.listOrderProductByOrderId(responseDTO.getData().getOrderId());
        if (CollectionUtil.isNotNullOrEmpty(newOrderProductList)) {
            List<String> productListLog = Lists.newArrayList();
            newOrderProductList.forEach(product->{
                String orderProductString = String.format("前台产品[%s]-后台产品[%s],数量:%s,品牌:%s", StringUtils.defaultIfBlank(product.getShowProductName(), "-"), StringUtils.defaultIfBlank(product.getProductName(), "-"),product.getNumber(), StringUtils.defaultIfBlank(product.getBrandName(), "-"));
                productListLog.add(orderProductString);
            });
            dro.setProductInfo(StringUtils.join(productListLog, "；"));
        }
        return ResponseDTO.success(dro);
    }

    @Override
    public ResponseDTO<Boolean> checkDuplicateOrder(Long orderId, Long workId) {
        try {
            OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
            // 处理重复工单ID
            Long duplicateOrderId = duplicateOrderBService.findDuplicateOrderId(orderWork);
            return ResponseDTO.success(Objects.nonNull(duplicateOrderId));
        } catch (Exception e) {
            log.error("校验取消重复异常 workId={} error={}", workId, e);
            return ResponseDTO.fail("取消重复单接口异常");
        }
    }
}
